from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework import status
from decimal import Decimal
import hashlib, hmac, datetime, pymysql
from django.conf import settings
from django.http import StreamingHttpResponse
from django.utils.encoding import escape_uri_path

from speeds.models import SpeedMerchantAuthDraw
from equity_mall.utils.utils import mmpaymkttransfers, mmpaymkttransfers_xh
from speeds.serializers import SpeedMerchantAuthDrawSerializer


class SpeedMerchantAuthDrawModelViewSet(ModelViewSet):

    serializer_class = SpeedMerchantAuthDrawSerializer

    def transfers(self, request):
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]#所以这里是真实的ip
        else:
            ip = request.META.get('REMOTE_ADDR')#这里获得代理ip
        print(ip)
        if ip not in ['118.178.240.32', '118.178.240.59', '121.196.223.219', '121.41.164.69', '47.96.229.8']:
            return Response({'code': 400, 'message': '非白名单内ip,请联系管理员处理'}, status=status.HTTP_200_OK)
        # data = self.request.data
        data = self.request.data.copy()
        print(data)
        sign = data.pop('sign', None)
        appid = data.get('appid', None)
        openid = data.get('openid', None)
        amount = data.get('amount', None)
        business_no = data.get('business_no', None)
        out_biz_no = data.get('out_biz_no', None)
        key = '01952c9ba8aru5h60ccfno5d8e52213a'
        if not sign:
            return Response({'code': 400, 'message': '缺少sign参数'}, status=status.HTTP_200_OK)
        if appid not in ['wx1cdf14a52b6b487b', 'wx6a8b87977c973635', 'wx69e93a9f3b188110']:
            return Response({'code': 400, 'message': '无效接入appid'}, status=status.HTTP_200_OK)
        if not openid:
            return Response({'code': 400, 'message': '缺少openid参数'}, status=status.HTTP_200_OK)
        if not business_no:
            return Response({'code': 400, 'message': '缺少business_no参数'}, status=status.HTTP_200_OK)
        if not amount:
            return Response({'code': 400, 'message': '缺少amount参数'}, status=status.HTTP_200_OK)
        if not out_biz_no:
            return Response({'code': 400, 'message': '缺少out_biz_no参数'}, status=status.HTTP_200_OK)
        business_no = str(business_no).replace(' ', '')
        if not business_no.isdigit() and len(business_no) != 10:
            return Response({'code': 400, 'message': 'business_no参数格式有误'}, status=status.HTTP_200_OK)
        try:
            amount = Decimal(amount)
        except:
            return Response({'code': 400, 'message': 'amount参数格式有误'}, status=status.HTTP_200_OK)
        if len(out_biz_no) > 32:
            return Response({'code': 400, 'message': 'out_biz_no参数格式有误'}, status=status.HTTP_200_OK)
        if len(openid) > 32:
            return Response({'code': 400, 'message': 'openid参数格式有误'}, status=status.HTTP_200_OK)
        params_list = sorted(data.items(), key=lambda e: e[0], reverse=False)  # 参数字典倒排序为列表
        params_str = "&".join(u"{}={}".format(k, v) for k, v in params_list)
        check_sign = hmac.new(bytes(key, encoding='utf-8'), bytes(params_str, encoding='utf-8'), digestmod=hashlib.sha256).digest().hex().upper()
        if sign[0] != check_sign and sign != check_sign:
            return Response({'code': 400, 'message': '签名错误'}, status=status.HTTP_200_OK)
        check_instance = SpeedMerchantAuthDraw.objects.filter(out_biz_no=out_biz_no)
        if check_instance:
            return Response({'code': 400, 'message': '重复out_biz_no'}, status=status.HTTP_200_OK)
        try:
            instance = SpeedMerchantAuthDraw.objects.get(business_no=business_no, appid=appid, amount=amount)
        except:
            return Response({'code': 400, 'message': '非有奖商户名单'}, status=status.HTTP_200_OK)
        if instance.amount != amount:
            return Response({'code': 400, 'message': '获奖金额与名单金额不一致'}, status=status.HTTP_200_OK)
        if instance.payment_status == 2:
            return Response({'code': 400, 'message': '奖励已被领取'}, status=status.HTTP_200_OK)
        if instance.payment_status == 3:
            return Response({'code': 400, 'message': '奖励领取失败,请联系管理员'}, status=status.HTTP_200_OK)
        if instance.platform == 1:
            params = {
                'mch_appid': appid,
                'mchid': '1486198522',  # 商户号
                'nonce_str': instance.nonce_str,
                'partner_trade_no': instance.partner_trade_no,
                'openid': openid,
                'check_name': 'NO_CHECK',
                'amount': int(instance.amount * 100),
                'desc': instance.desc
            }
            data_dict = mmpaymkttransfers(params)
        else:
            params = {
                'mch_appid': appid,
                'mchid': '1571060401',  # 商户号
                'nonce_str': instance.nonce_str,
                'partner_trade_no': instance.partner_trade_no,
                'openid': openid,
                'check_name': 'NO_CHECK',
                'amount': int(instance.amount * 100),
                'desc': instance.desc
            }
            data_dict = mmpaymkttransfers_xh(params)
        if data_dict['result_code'] == 'SUCCESS':
            instance.payment_time = data_dict['payment_time']
            instance.payment_no = data_dict['payment_no']
            instance.payment_status = 2
            instance.openid = openid
            instance.out_biz_no = out_biz_no
            instance.save()
            return Response({'message': '付款成功,请留意【微信支付】公众号-【商家转账入账通知】', 'code': 200}, status=status.HTTP_200_OK)
        else:
            if data_dict['err_code'] == 'AMOUNT_LIMIT':
                err_code_des = '被微信风控拦截，最低单笔付款限额调整为5元。'
                err_code = 10001
            elif data_dict['err_code'] == 'NOTENOUGH':
                err_code_des = '余额不足。'
                err_code = 10002
            elif data_dict['err_code'] == 'SYSTEMERROR':
                err_code_des = '微信内部接口调用发生错误。'
                err_code = 10003
            elif data_dict['err_code'] == 'NAME_MISMATCH':
                err_code_des = '收款人身份校验不通过。'
                err_code = 10004
            elif data_dict['err_code'] == 'FREQ_LIMIT':
                err_code_des = '接口请求频率超时接口限制。'
                err_code = 10005
            elif data_dict['err_code'] == 'MONEY_LIMIT':
                err_code_des = '已经达到今日付款总额上限/已达到付款给此用户额度上限。'
                err_code = 10006
            elif data_dict['err_code'] == 'V2_ACCOUNT_SIMPLE_BAN':
                err_code_des = '用户微信支付账户未知名，无法付款。'
                err_code = 10007
            elif data_dict['err_code'] == 'SENDNUM_LIMIT':
                err_code_des = '该用户今日付款次数超过限制'
                err_code_des1 = '该用户今日付款次数超过限制,如有需要请进入【微信支付商户平台-产品中心-企业付款到零钱-产品设置】进行修改。'
                err_code = 10008
            else:
                err_code_des = '其他未知错误。'
                err_code = 10009
            instance.return_msg = data_dict['err_code_des']
            instance.payment_status = 3
            instance.openid = openid
            instance.payment_time = datetime.datetime.now()
            instance.out_biz_no = out_biz_no
            instance.save()
            return Response({'message': f'{err_code_des}', 'code': 400}, status=status.HTTP_200_OK)

    def wyh_transfers(self, request):
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]#所以这里是真实的ip
        else:
            ip = request.META.get('REMOTE_ADDR')#这里获得代理ip
        print(ip)
        if ip not in ['118.178.240.32', '118.178.240.59', '121.196.223.219', '121.41.164.69', '47.96.229.8', '61.140.180.179']:
            return Response({'code': 400, 'message': '非白名单内ip,请联系管理员处理'}, status=status.HTTP_200_OK)
        # data = self.request.data
        data = self.request.data.copy()
        print(data)
        sign = data.pop('sign', None)
        appid = data.get('appid', None)
        openid = data.get('openid', None)
        amount = data.get('amount', None)
        business_no = data.get('business_no', None)
        out_biz_no = data.get('out_biz_no', None)
        key = '01952c9ba8aru5h60ccfno5d8e52213a'
        if not sign:
            return Response({'code': 400, 'message': '缺少sign参数'}, status=status.HTTP_200_OK)
        if appid not in ['wx1cdf14a52b6b487b', 'wx6a8b87977c973635', 'wx69e93a9f3b188110']:
            return Response({'code': 400, 'message': '无效接入appid'}, status=status.HTTP_200_OK)
        if not openid:
            return Response({'code': 400, 'message': '缺少openid参数'}, status=status.HTTP_200_OK)
        if not business_no:
            return Response({'code': 400, 'message': '缺少business_no参数'}, status=status.HTTP_200_OK)
        if not amount:
            return Response({'code': 400, 'message': '缺少amount参数'}, status=status.HTTP_200_OK)
        if not out_biz_no:
            return Response({'code': 400, 'message': '缺少out_biz_no参数'}, status=status.HTTP_200_OK)
        business_no = str(business_no).replace(' ', '')
        if not business_no.isdigit() and len(business_no) != 10:
            return Response({'code': 400, 'message': 'business_no参数格式有误'}, status=status.HTTP_200_OK)
        try:
            amount = Decimal(amount)
        except:
            return Response({'code': 400, 'message': 'amount参数格式有误'}, status=status.HTTP_200_OK)
        if len(out_biz_no) > 32:
            return Response({'code': 400, 'message': 'out_biz_no参数格式有误'}, status=status.HTTP_200_OK)
        if len(openid) > 32:
            return Response({'code': 400, 'message': 'openid参数格式有误'}, status=status.HTTP_200_OK)
        params_list = sorted(data.items(), key=lambda e: e[0], reverse=False)  # 参数字典倒排序为列表
        params_str = "&".join(u"{}={}".format(k, v) for k, v in params_list)
        check_sign = hmac.new(bytes(key, encoding='utf-8'), bytes(params_str, encoding='utf-8'), digestmod=hashlib.sha256).digest().hex().upper()
        if sign[0] != check_sign and sign != check_sign:
            return Response({'code': 400, 'message': '签名错误'}, status=status.HTTP_200_OK)
        check_instance = SpeedMerchantAuthDraw.objects.filter(out_biz_no=out_biz_no)
        if check_instance:
            return Response({'code': 400, 'message': '重复out_biz_no'}, status=status.HTTP_200_OK)
        try:
            instance = SpeedMerchantAuthDraw.objects.get(business_no=business_no, appid=appid, platform=2)
        except:
            return Response({'code': 400, 'message': '非有奖商户名单'}, status=status.HTTP_200_OK)
        if instance.amount != amount:
            return Response({'code': 400, 'message': '获奖金额与名单金额不一致'}, status=status.HTTP_200_OK)
        if instance.payment_status == 2:
            return Response({'code': 400, 'message': '奖励已被领取'}, status=status.HTTP_200_OK)
        if instance.payment_status == 3:
            return Response({'code': 400, 'message': '奖励领取失败,请联系管理员'}, status=status.HTTP_200_OK)
        params = {
            'mch_appid': appid,
            'mchid': '1571060401',  # 商户号
            'nonce_str': instance.nonce_str,
            'partner_trade_no': instance.partner_trade_no,
            'openid': openid,
            'check_name': 'NO_CHECK',
            'amount': int(instance.amount * 100),
            'desc': instance.desc
        }
        data_dict = mmpaymkttransfers_xh(params)
        if data_dict['result_code'] == 'SUCCESS':
            instance.payment_time = data_dict['payment_time']
            instance.payment_no = data_dict['payment_no']
            instance.payment_status = 2
            instance.openid = openid
            instance.out_biz_no = out_biz_no
            instance.save()
            return Response({'message': '付款成功,请留意【微信支付】公众号-【商家转账入账通知】', 'code': 200}, status=status.HTTP_200_OK)
        else:
            if data_dict['err_code'] == 'AMOUNT_LIMIT':
                err_code_des = '被微信风控拦截，最低单笔付款限额调整为5元。'
                err_code = 10001
            elif data_dict['err_code'] == 'NOTENOUGH':
                err_code_des = '余额不足。'
                err_code = 10002
            elif data_dict['err_code'] == 'SYSTEMERROR':
                err_code_des = '微信内部接口调用发生错误。'
                err_code = 10003
            elif data_dict['err_code'] == 'NAME_MISMATCH':
                err_code_des = '收款人身份校验不通过。'
                err_code = 10004
            elif data_dict['err_code'] == 'FREQ_LIMIT':
                err_code_des = '接口请求频率超时接口限制。'
                err_code = 10005
            elif data_dict['err_code'] == 'MONEY_LIMIT':
                err_code_des = '已经达到今日付款总额上限/已达到付款给此用户额度上限。'
                err_code = 10006
            elif data_dict['err_code'] == 'V2_ACCOUNT_SIMPLE_BAN':
                err_code_des = '用户微信支付账户未知名，无法付款。'
                err_code = 10007
            elif data_dict['err_code'] == 'SENDNUM_LIMIT':
                err_code_des = '该用户今日付款次数超过限制'
                err_code_des1 = '该用户今日付款次数超过限制,如有需要请进入【微信支付商户平台-产品中心-企业付款到零钱-产品设置】进行修改。'
                err_code = 10008
            else:
                err_code_des = '其他未知错误。'
                err_code = 10009
            instance.return_msg = data_dict['err_code_des']
            instance.payment_status = 3
            instance.openid = openid
            instance.payment_time = datetime.datetime.now()
            instance.out_biz_no = out_biz_no
            instance.save()
            return Response({'message': f'{err_code_des}', 'code': 400}, status=status.HTTP_200_OK)

    def export_merchant_auth(self, request):
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        sql = 'SELECT *,DATE_FORMAT(payment_time,"%Y-%m-%d %H:%i:%S")AS payment_time FROM tb_speed_merchant_auth_draw WHERE platform=2;'
        cursor.execute(sql)
        ziduan = ['商户号', '小程序appid', 'openid', '金额(元)', '第三方订单号', '订单号', '说明', '交易流水号', '付款状态', '付款时间']
        cols = ['business_no', 'appid', 'openid', 'amount', 'out_biz_no', 'partner_trade_no', 'desc', 'payment_no', 'payment_status', 'payment_time']
        response = StreamingHttpResponse(self.get_merchant_auth_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('双微商户月月免单活动领取明细.csv'))
        return response

    def get_merchant_auth_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        PAYMENT_STATUS_ENUM = {
            1: '未领取',
            2: '已领取',
            3: '领取失败'
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'payment_status':
                    tmp_str += '"%s",' % (PAYMENT_STATUS_ENUM[row[col]])
                elif col in ['out_biz_no', 'partner_trade_no', 'payment_no']:
                    tmp_str += '"\'%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"